//      xfer.c
//      
//      Copyright 2011 DJ Shaji <djshaji@gmail.com>
//      
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//      
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//      
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.


#include "xfer.h"

void xfer_update_copy_process ( goffset current, goffset total, Copy * copy )
{
	gtk_progress_bar_set_fraction ( copy -> bar1, ( gfloat ) current / ( gfloat ) total ) ;
	gtk_progress_bar_set_fraction ( copy -> bar2, ( gfloat ) copy -> current_file / ( gfloat ) copy -> total_files ) ;
	
	april_update_gui () ;
}

void xfer_populate_folder ( GList * list, gchar * folder )
{
	GError * error = null ;
	GDir * dir = g_dir_open ( folder, 0, & error ) ;
	
	if ( error )
	{
		g_warning ( "Cannot read folder: %s", error -> message ) ;
		return ;
	
	}
	
	gchar * name = g_dir_read_name ( dir ) ;
	while ( name )
	{
		gchar * full_name = g_build_filename ( folder, name, null ) ;
		list = g_list_append ( list, full_name ) ;
		
		if ( g_file_test ( full_name, G_FILE_TEST_IS_DIR ))
			xfer_populate_folder ( list, full_name ) ;
			
		name = g_dir_read_name ( dir ) ;
	}
	
	g_dir_close ( dir ) ;
}
		


void xfer_copy ( Explorer * e, gchar * source, gchar * destination )
{
	GtkDialog * dialog = gtk_dialog_new_with_buttons ( "Copying files ...",
							e -> window,
							GTK_DIALOG_MODAL,
							"Cancel",
							0,
							null ) ;
	
	GtkImage * image = gtk_image_new_from_stock ( "gtk-copy", GTK_ICON_SIZE_DIALOG ) ;
	gchar * markup = g_markup_printf_escaped ( 
						"<span size=\"large\"><b>"
						"Copying files ...\n\n"
						"</b></span>"
						"Please wait while files are being copied." ) ;
	
	GtkLabel * l = gtk_label_new ( null ) ;
	gtk_label_set_markup ( l, markup ) ;
	
	g_free ( markup ) ;
	
	GtkWidget * hbox = gtk_hbox_new ( no, 0 ) ;
	GtkWidget * vbox = gtk_hbox_new ( no, 0 ) ;
	
	gtk_box_pack_start ( hbox, image, no, no, 5 ) ;
	gtk_box_pack_start ( hbox, l, yes, yes, 2 ) ;
	
	gtk_box_pack_start ( vbox, hbox, yes, yes, 5 ) ;
	gtk_label_set_line_wrap ( l, on ) ;

	GtkProgressBar  * bar1 = gtk_progress_bar_new (),
					* bar2 = gtk_progress_bar_new () ;
	
	gtk_box_pack_start ( vbox, bar1, no, no, 2 ) ;
	gtk_box_pack_start ( vbox, bar2, no, no, 2 ) ;
	
	gtk_box_pack_start ( dialog -> vbox, vbox, yes, yes, 5 ) ;
	gtk_widget_show_all ( dialog ) ;
	
	GList * list = null ;
	if ( g_file_test ( source, G_FILE_TEST_IS_DIR ))
		xfer_populate_folder ( list, source ) ;
	else
		list = g_list_append ( list, g_strdup ( source )) ;
	
	gint i = 0, len = g_list_length ( list ) ;
	GCancellable * cancellable = g_cancellable_new () ;
	
	Copy copy ;
	
	copy.bar1 = bar1 ;
	copy.bar2 = bar2 ;
	
	copy.list = list ;
	copy.total_files = len ;
	
	copy.current_file = 0 ;
	copy.cancellable = cancellable ;
	
	gboolean source_file_is_regular = g_file_test ( source, G_FILE_TEST_IS_REGULAR ) ;
	
	for ( i = 0 ; i < len ; i ++ )
	{
		GFile * f1 = g_file_new_for_path ( g_list_nth_data ( list, i )),
			  * f2 = null ;
		
		copy.current_file = i ;
		
		if ( source_file_is_regular )
		{
			copy.current_file = 1 ;
			copy.total_files = 2 ;
			
			f2 = g_file_new_for_path ( destination ) ;
			GError * error = null ;
			
			if ( g_file_test ( destination, G_FILE_TEST_EXISTS ))
			{
				gchar * m = g_strdup_printf ( "The file %s exists. Overwrite ?", destination ) ;
				if ( prompt_question ( m ))
					g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
									& copy, e, & error ) ;
				
				g_free ( m ) ;
			}
			
			else
				g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
					& copy, e, & error ) ;

			if ( error )
				g_critical ( "Cannot copy file: %s", error -> message ) ;
				
			g_object_unref ( cancellable ) ;
			g_object_unref ( f1 ) ;
			
			g_object_unref ( f2 ) ;
			
			g_list_foreach ( list, g_free, null ) ;
			g_list_free ( list ) ;
			
			gtk_widget_destroy ( dialog ) ;
			return ;
		}

		gchar * new_name = g_build_filename ( source, g_list_nth_data ( list, i ), null ) ;
		
		/* We might not need this
		if ( g_file_test ( g_list_nth_data ( list, i ), G_FILE_TEST_IS_DIR ))
			g_mkdir_with_parents ( new_name, 0777 ) ;
		*/
		
		f2 = g_file_new_for_path ( new_name ) ;
		GError * error = null ;
		
		if ( g_file_test ( new_name, G_FILE_TEST_EXISTS ) && ! g_file_test ( new_name, G_FILE_TEST_IS_DIR ))
		{
			gchar * m = g_strdup_printf ( "The file %s exists. Overwrite ?", new_name ) ;
			if ( prompt_question ( m ))
				g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
						xfer_update_copy_process, & copy, & error ) ;
		
			g_free ( m ) ;
		}
		else
			g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
					xfer_update_copy_process, & copy, & error ) ;
		
		if ( error )
			g_critical ( "Cannot copy file: %s", error -> message ) ;
		
		g_object_unref ( f1 ) ;
		g_object_unref ( f2 ) ;
		
		g_free ( new_name ) ;
	}
	
	
	g_object_unref ( cancellable ) ;
	g_list_foreach ( list, g_free, null ) ;
	
	g_list_free ( list ) ;
	gtk_widget_destroy ( dialog ) ;
}


///| Double vision ?
void xfer_copy_list ( Explorer * e, GList * list, gchar * destination )
{
	if ( ! g_file_test ( destination, G_FILE_TEST_IS_DIR ))
	{
		g_warning ( "Cannot copy multiple files to something "
					"other than a directory. Yea" ) ;
		
		return ;
	}
	
	GtkDialog * dialog = gtk_dialog_new_with_buttons ( "Copying files ...",
							e -> window,
							GTK_DIALOG_MODAL,
							"Cancel",
							0,
							null ) ;
	
	GtkImage * image = gtk_image_new_from_stock ( "gtk-copy", GTK_ICON_SIZE_DIALOG ) ;
	gchar * markup = g_markup_printf_escaped ( 
						"<span size=\"large\"><b>"
						"Copying files ...\n\n"
						"</b></span>"
						"Please wait while files are being copied." ) ;
	
	GtkLabel * l = gtk_label_new ( null ) ;
	gtk_label_set_markup ( l, markup ) ;
	
	g_free ( markup ) ;
	
	GtkWidget * hbox = gtk_hbox_new ( no, 0 ) ;
	GtkWidget * vbox = gtk_hbox_new ( no, 0 ) ;
	
	gtk_box_pack_start ( hbox, image, no, no, 5 ) ;
	gtk_box_pack_start ( hbox, l, yes, yes, 2 ) ;
	
	gtk_box_pack_start ( vbox, hbox, yes, yes, 5 ) ;
	gtk_label_set_line_wrap ( l, on ) ;

	GtkProgressBar  * bar1 = gtk_progress_bar_new (),
					* bar2 = gtk_progress_bar_new () ;
	
	gtk_box_pack_start ( vbox, bar1, no, no, 2 ) ;
	gtk_box_pack_start ( vbox, bar2, no, no, 2 ) ;
	
	gtk_box_pack_start ( dialog -> vbox, vbox, yes, yes, 5 ) ;
	gtk_widget_show_all ( dialog ) ;
	
	gint i = 0, len = g_list_length ( list ) ;
	GCancellable * cancellable = g_cancellable_new () ;
	
	Copy copy ;
	
	copy.bar1 = bar1 ;
	copy.bar2 = bar2 ;
	
	copy.list = list ;
	copy.total_files = len ;
	
	copy.current_file = 0 ;
	copy.cancellable = cancellable ;
	
	gchar * source = explorer_get_current_folder ( e ) ;
	
	for ( i = 0 ; i < len ; i ++ )
	{
		GFile * f1 = g_file_new_for_path ( g_list_nth_data ( list, i )),
			  * f2 = null ;
		
		gchar * new_name = g_build_filename ( source, g_list_nth_data ( list, i ), null ) ;
		copy.current_file = i ;
		
		/* We might not need this
		if ( g_file_test ( g_list_nth_data ( list, i ), G_FILE_TEST_IS_DIR ))
			g_mkdir_with_parents ( new_name, 0777 ) ;
		*/
		
		f2 = g_file_new_for_path ( new_name ) ;
		GError * error = null ;
		
		if ( g_file_test ( new_name, G_FILE_TEST_EXISTS ) && ! g_file_test ( new_name, G_FILE_TEST_IS_DIR ))
		{
			gchar * m = g_strdup_printf ( "The file %s exists. Overwrite ?", new_name ) ;
			if ( prompt_question ( m ))
				g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
						& copy, e, & error ) ;
		
			g_free ( m ) ;
		}
		else
			g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
					& copy, e, & error ) ;
		
		if ( error )
			g_critical ( "Cannot copy file: %s", error -> message ) ;
		
		g_object_unref ( f1 ) ;
		g_object_unref ( f2 ) ;
		
		g_free ( new_name ) ;
	}
	
	
	g_object_unref ( cancellable ) ;
	g_list_foreach ( list, g_free, null ) ;
	
	g_list_free ( list ) ;
	gtk_widget_destroy ( dialog ) ;
	
	g_free ( source ) ;
}

void xfer_xfer ( Explorer * e, ClipboardAction action, GList * list, gchar * destination )
{
	if ( ! g_file_test ( destination, G_FILE_TEST_IS_DIR ))
	{
		g_warning ( "Cannot copy multiple files to something "
					"other than a directory. Yea" ) ;
		
		return ;
	}
	
	GtkDialog * dialog = null ;
	GtkImage * image = null ;
	
	gchar * markup = null ;
	
	if ( action == COPY )
	{
	
		dialog = gtk_dialog_new_with_buttons ( "Copying files ...",
								e -> window,
								GTK_DIALOG_MODAL,
								null ) ;
		
	
		image = gtk_image_new_from_stock ( "gtk-copy", GTK_ICON_SIZE_DIALOG ) ;
		markup = g_markup_printf_escaped ( 
							"<span size=\"large\"><b>"
							"Copying files ...\n\n"
							"</b></span>"
							"Please wait while files are being copied." ) ;
	}
	
	else
	{
	
		dialog = gtk_dialog_new_with_buttons ( "Moving files ...",
								e -> window,
								GTK_DIALOG_MODAL,
								null ) ;
		
		image = gtk_image_new_from_stock ( "gtk-cut", GTK_ICON_SIZE_DIALOG ) ;
		markup = g_markup_printf_escaped ( 
							"<span size=\"large\"><b>"
							"Moving files ...\n\n"
							"</b></span>"
							"Please wait while files are being moved." ) ;
	}

	GtkButton * button = gtk_button_new_with_label ( "Cancel" ) ;
	gtk_box_pack_end ( dialog -> action_area, button, no, no, 2 ) ;
	
	GtkLabel * l = gtk_label_new ( null ) ;
	gtk_label_set_markup ( l, markup ) ;
	
	g_free ( markup ) ;
	
	GtkWidget * hbox = gtk_hbox_new ( no, 0 ) ;
	GtkWidget * vbox = gtk_hbox_new ( no, 0 ) ;
	
	gtk_box_pack_start ( hbox, image, no, no, 5 ) ;
	gtk_box_pack_start ( hbox, l, yes, yes, 2 ) ;
	
	gtk_box_pack_start ( vbox, hbox, yes, yes, 5 ) ;
	gtk_label_set_line_wrap ( l, on ) ;

	GtkProgressBar  * bar1 = gtk_progress_bar_new (),
					* bar2 = gtk_progress_bar_new () ;
	
	gtk_box_pack_start ( dialog -> vbox, vbox, yes, yes, 5 ) ;
	
	gtk_box_pack_start ( dialog -> vbox, bar1, no, no, 5 ) ;
	gtk_box_pack_start ( dialog -> vbox, bar2, no, no, 2 ) ;
	
	gtk_widget_show_all ( dialog ) ;
	gint i = 0, len = g_list_length ( list ) ;

	GCancellable * cancellable = g_cancellable_new () ;
	g_signal_connect_swapped ( button, "clicked", g_cancellable_cancel, cancellable ) ;
	
	Copy copy ;
	
	copy.bar1 = bar1 ;
	copy.bar2 = bar2 ;
	
	copy.list = list ;
	copy.total_files = len ;
	
	copy.current_file = 0 ;
	copy.cancellable = cancellable ;
	
	for ( i = 0 ; i < len ; i ++ )
	{
		if ( g_cancellable_is_cancelled ( cancellable ))
			break ;
		
		gchar * path = g_list_nth_data ( list, i ) ;
		copy.current_file = i ;
		
		if ( g_file_test ( path, G_FILE_TEST_IS_DIR ))
		{
			gchar * basename = g_path_get_basename ( path ) ;
			gchar * new_name = g_build_filename ( destination, basename, null ) ;
			
			_copy_files_recursively ( e, & copy, path, new_name ) ;
			
			g_free ( basename ) ;
			g_free ( new_name ) ;
			
			fm_append_to_store ( e, path ) ;
			gtk_progress_bar_set_text ( copy.bar2, " " ) ;
			
			continue ;
		}
		
		gchar * basename = g_path_get_basename ( path ) ;
		gchar * new_name = g_build_filename ( destination, basename, null ) ;
		
		GFile * f1 = g_file_new_for_path ( path ),
			  * f2 = g_file_new_for_path ( new_name ) ;
		
		g_debug ( "[%s] Copying %s to %s", __func__, path, new_name ) ;
		copy.current_file = i ;
		
		GError * error = null ;
		
		if ( g_file_test ( new_name, G_FILE_TEST_EXISTS ))
		{
			gchar * message = g_strdup_printf
				( "The file %s exists. Overwrite ?", new_name ) ;
			
			if ( prompt_question == YES )
				g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
					xfer_update_copy_process, & copy, & error ) ;
			
				
		}
		
		else
		{
			g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, cancellable,
				xfer_update_copy_process, & copy, & error ) ;
		}
			
		
		if ( error )
			prompt_error ( error -> message ) ;
		else
			fm_append_to_store ( e, path ) ;
	
		g_object_unref ( f1 ) ;
		g_object_unref ( f2 ) ;
		
		g_free ( basename ) ;
		g_free ( new_name ) ;
	}
	
	g_object_unref ( cancellable ) ;
	gtk_widget_destroy ( dialog ) ;
	
}

void xfer_delete ( Explorer * e, GList * list )
{
	gchar * message = null ;
	gint i = 0, len = g_list_length ( list ) ;
	
	if ( len == 1 )
	{
		message = g_strdup_printf ( "Are you sure you want to delete %s ?", 
						g_list_nth_data ( list, 0 )) ;
		
		if ( ! prompt_question ( message ) == YES )
		{
			g_free ( message ) ;
			return ;
		}
	}
	
	else
	{
		message = g_strdup_printf ( "Are you sure you want to delete %d files ?",
									len ) ;
		
		if ( ! prompt_question ( message ) == YES )
		{
			g_free ( message ) ;
			return ;
		}
	}
	
	GtkDialog * dialog = gtk_dialog_new_with_buttons ( "Deleting files ...",
							e -> window,
							GTK_DIALOG_MODAL,
							null ) ;
	
	GtkImage * image = gtk_image_new_from_stock ( "gtk-copy", GTK_ICON_SIZE_DIALOG ) ;
	gchar * markup = g_markup_printf_escaped ( 
						"<span size=\"large\"><b>"
						"Deleting files ...\n\n"
						"</b></span>"
						"Please wait while files are being deleted." ) ;
	
	GtkButton * b = gtk_button_new_with_label ( "Cancel" ) ;
	gtk_box_pack_start ( dialog -> action_area, b, no, no, 2 ) ;

	GtkLabel * l = gtk_label_new ( null ) ;
	gtk_label_set_markup ( l, markup ) ;
	
	g_free ( markup ) ;
	
	GtkWidget * hbox = gtk_hbox_new ( no, 0 ) ;
	GtkWidget * vbox = gtk_hbox_new ( no, 0 ) ;
	
	gtk_box_pack_start ( hbox, image, no, no, 5 ) ;
	gtk_box_pack_start ( hbox, l, yes, yes, 2 ) ;
	
	gtk_box_pack_start ( vbox, hbox, yes, yes, 5 ) ;
	gtk_label_set_line_wrap ( l, on ) ;

	GtkProgressBar  * bar1 = gtk_progress_bar_new () ;	
	gtk_box_pack_start ( dialog -> vbox, vbox, yes, yes, 5 ) ;
	gtk_box_pack_start ( dialog -> vbox, bar1, no, no, 2 ) ;
	
	gtk_widget_show_all ( dialog ) ;

	GCancellable * cancellable = g_cancellable_new () ;
	g_signal_connect_swapped ( b, "clicked", g_cancellable_cancel, cancellable ) ;
	
	Copy copy ;
	
	copy.bar1 = bar1 ;
	
	copy.list = list ;
	copy.total_files = len ;
	
	copy.current_file = 0 ;
	copy.cancellable = cancellable ;

	gboolean mark_for_refresh = false ;

	for ( i = 0 ; i < len ; i ++ )
	{
		if ( g_cancellable_is_cancelled ( cancellable ))
			break ;

		gchar * path = g_list_nth_data ( list, i ) ;
		if ( g_file_test ( path, G_FILE_TEST_IS_DIR ))
		{
			_delete_files_recursively ( e, & copy, path ) ;
			
		}
		else
		{
			GFile * f = g_file_new_for_path ( path ) ;
			GError * error = null ;
			
			g_file_delete ( f, cancellable, & error ) ;
			g_debug ( "[%s] Deleted %s", __func__, path ) ;
			
			if ( error )
			{
				prompt_error ( error -> message ) ;
			}
			else
			{
				GtkTreeIter iter ;
				if ( _find_path_in_store ( e, path, & iter ))
					gtk_list_store_remove ( e -> store, & iter ) ;
				else
					mark_for_refresh = true ;
			
				g_object_unref ( f ) ;
			}
		}
		
		gtk_progress_bar_pulse ( bar1 ) ;
		april_update_gui () ;
	}
	
	g_object_unref ( cancellable ) ;
	gtk_widget_destroy ( dialog ) ;
}

gboolean _find_path_in_store ( Explorer * e, gchar * path, GtkTreeIter * iter )
{
	gboolean run = gtk_tree_model_get_iter_first ( e -> store, iter ) ;
	
	while ( run )
	{
		gchar * p = null ;
		gtk_tree_model_get ( e -> store, iter, 2, & p, -1 ) ;
		
		if ( strcmp ( p, path ) == 0 )
		{
			g_free ( p ) ;
			return run ;
		}

		g_free ( p ) ;
		run = gtk_tree_model_iter_next ( e -> store, iter ) ;
	}
	
	return run ;
}

void _delete_files_recursively ( Explorer * e, Copy * c, gchar * path )
{
	GError * error = null ;
	GDir * dir = g_dir_open ( path, 0, & error ) ;
	
	gchar * name = g_dir_read_name ( dir ) ;
	while ( name )
	{
		if ( g_cancellable_is_cancelled ( c -> cancellable ))
			break ;
			
		gchar * full_name = g_build_filename ( path, name, null ) ;
		
		if ( g_file_test ( full_name, G_FILE_TEST_IS_DIR ))
		{
			_delete_files_recursively ( e, c, full_name ) ;
		}
		else
		{
			GFile * f = g_file_new_for_path ( full_name ) ;
			GError * error = null ;
			
			g_file_delete ( f, c -> cancellable, & error ) ;
			g_debug ( "Deleted %s", full_name ) ;
			
			if ( error )
				prompt_error ( error -> message ) ;
			
			g_object_unref ( f ) ;
		}

		g_free ( full_name ) ;
		name = g_dir_read_name ( dir ) ;
		
		gtk_progress_bar_pulse ( c -> bar1 ) ;
		april_update_gui () ;
	}
	
	g_dir_close ( dir ) ;
	
	GFile * f = g_file_new_for_path ( path ) ;
	
	g_file_delete ( f, c -> cancellable, & error ) ;
	g_debug ( "[%s] Deleted %s", __func__, path ) ;
	
	if ( error )
		prompt_error ( error -> message ) ;
	else
	{
		GtkTreeIter iter ;
		if ( _find_path_in_store ( e, path, & iter ))
			gtk_list_store_remove ( e -> store, & iter ) ;
	}			
	
	
	g_object_unref ( f ) ;

}

void _defunct_copy_files_recursively ( Explorer * e, Copy * c, gchar * source, gchar * dest )
{
	g_debug ( "[%s] source_dir: %s dest_dit %s", __func__, source, dest ) ;
	
	GError * error = null ;
	GDir * dir = g_dir_open ( source, 0, & error ) ;
	
	if ( error )
	{
		prompt_error ( error -> message ) ;
		return ;
	}
	
	gchar * name = g_dir_read_name ( dir ) ;
	gchar * basename = g_path_get_basename ( source ) ;

	gchar * new_folder = g_build_filename ( dest, basename, null ) ;
	
	g_mkdir_with_parents ( new_folder, 0700 ) ;
	g_debug ( "Creating folder %s", new_folder ) ;
	
	while ( name )
	{
		g_debug ( name ) ;
		
		gchar * full_name = g_build_filename ( source, name, null ) ;
		gchar * new_name = g_build_filename ( new_folder, name, null ) ;
		
		if ( g_file_test ( full_name, G_FILE_TEST_IS_DIR ))
		{
	//		if ( ! g_file_test ( new_name, G_FILE_TEST_EXISTS ))
		//		g_mkdir ( new_name, 0777 ) ;
			
		//	_copy_files_recursively ( e, c, full_name, new_name ) ;
		}
		else
		{
			GError * error = null ;
			GFile * f1 = g_file_new_for_path ( full_name ),
				  *	f2 = g_file_new_for_path ( new_name ) ;
			
			if ( g_file_test ( new_name, G_FILE_TEST_EXISTS ))
			{
				gchar * message = g_strdup_printf (
					"The file %s already exists. Overwrite ?", new_name ) ;
				
				if ( prompt_question ( message ) == YES )
					g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, c -> cancellable, 
									xfer_update_copy_process, c, & error ) ;
				
				g_free ( message ) ;
			}
			
			else
			{
				g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, c -> cancellable, 
					xfer_update_copy_process, c, & error ) ;
			}
			
			if ( error )
				prompt_error ( error -> message ) ;
			
			g_object_unref ( f1 ) ;
			g_object_unref ( f2 ) ;
			
		}
		
		//g_debug ( "[%s] Copied %s to %s", __func__, full_name, new_name ) ;
		
		g_free ( full_name ) ;
		g_free ( new_name ) ;
		
		name = g_dir_read_name ( dir ) ;
	}
	
	g_free ( basename ) ;
	g_free ( new_folder ) ;
	
	g_dir_close ( dir ) ;
}


void _copy_files_recursively ( Explorer * e, Copy *c, gchar * source, gchar * dest )
{
	gtk_progress_bar_set_text ( c -> bar2, source ) ;
	
	GError * error = null ;
	GDir * dir = g_dir_open ( source, 0, & error ) ;
	
	if ( error )
	{
		g_critical ( error -> message ) ;
		return ;
	}
	
	if ( ! g_file_test ( dest, G_FILE_TEST_EXISTS ))
		g_mkdir ( dest, 0700 ) ;
	
	c -> total_files = 0 ;
	c -> current_file = 0 ;
	
	while ( g_dir_read_name ( dir ))
		c -> total_files ++ ;
	
	g_dir_rewind ( dir ) ;
	
	gchar * name = g_dir_read_name ( dir ) ;
	while ( name )
	{
		if ( g_cancellable_is_cancelled ( c -> cancellable ))
			break ;

		gchar * filename = g_build_filename ( source, name, null ) ;
		gchar * new_name = g_build_filename ( dest, name, null ) ;
		
		if ( g_file_test ( filename, G_FILE_TEST_IS_DIR ))
		{
			_copy_files_recursively ( e, c, filename, new_name ) ;
		}
		else
		{
			GFile * f1 = g_file_new_for_path ( filename ),
				  * f2 = g_file_new_for_path ( new_name ) ;
			
			GError * error = null ;
			
			g_file_copy ( f1, f2, G_FILE_COPY_OVERWRITE, c -> cancellable,
							xfer_update_copy_process, c, & error ) ;
			
			g_debug ( "[%s] Copied %s", __func__, new_name ) ;
			
			if ( error )
				g_critical ( error -> message ) ;
				
			g_object_unref ( f1 ) ;
			g_object_unref ( f2 ) ;
			
		}
		
		g_free ( filename ) ;
		g_free ( new_name ) ;
		
		c -> current_file ++ ;
		name = g_dir_read_name ( dir ) ;
	}
	
	g_dir_close ( dir ) ;
			
}

	
	
